package starfield;

import starfield.util.JSONUtils;
import java.io.IOException;
import java.util.Arrays;
import org.apache.commons.validator.routines.UrlValidator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.markdown4j.Markdown4jProcessor;

public class Metadata {
	public static final String KEY_METADATA = "metadata";
	public static final String KEY_TITLE = "title";
	public static final String KEY_DESCRIPTION = "description";
	public static final String KEY_SUPPORT_URL = "supportUrl";
	public static final String KEY_AUTHORS = "authors";
	public static final String KEY_VERSION = "version";
	
	protected String title;
	protected String description;
	protected String supportUrl;
	protected String[] authors;
	protected MetadataVersion version;
		
	public void deserialize(JSONObject json) throws ParsingException {
		if (json.containsKey(KEY_TITLE)) {
			title = JSONUtils.getString(json, KEY_TITLE);
		}

		if (json.containsKey(KEY_DESCRIPTION)) {
			description = JSONUtils.getString(json, KEY_DESCRIPTION);
		}

		if (json.containsKey(KEY_AUTHORS)) {
			JSONArray authorsJson = JSONUtils.getArray(json, KEY_AUTHORS);

			String[] authorsTemp = new String[authorsJson.size()];

			for (int i = 0; i < authorsJson.size(); i++) {
				authorsTemp[i] = JSONUtils.getString(authorsJson, i);
			}

			authors = authorsTemp;
		}

		if (json.containsKey(KEY_SUPPORT_URL)) {
			supportUrl = JSONUtils.getString(json, KEY_SUPPORT_URL);
		}

		if (json.containsKey(KEY_VERSION)) {
			try {
				version = MetadataVersion.parse(JSONUtils.getString(json, KEY_VERSION));
			} catch (ValidationException ex) {
				//throw new ParsingException("Invalid version string.");
			}
		}
	}
	
	public JSONObject serialize() {
		JSONObject metadataJson = new JSONObject();
		
		metadataJson.put(KEY_TITLE, title);
		metadataJson.put(KEY_DESCRIPTION, description);
		metadataJson.put(KEY_SUPPORT_URL, supportUrl);
		
		JSONArray authorsJson = new JSONArray();
		authorsJson.addAll(Arrays.asList(authors));
		
		metadataJson.put(KEY_AUTHORS, authorsJson);
		metadataJson.put(KEY_VERSION, version.toString());
		
		return metadataJson;
	}
	
	public String getTitle() {
		return title;
	}

	public String getDescription() {
		return description;
	}

	public String getSupportUrl() {
		return supportUrl;
	}

	public String[] getAuthors() {
		return authors;
	}
	
	public String getAuthorsString() {
		if (authors == null) {
			return "";
		} else {
			StringBuilder sb = new StringBuilder();

			String delimiter = "";

			for (String author : authors) {
				sb.append(delimiter).append(author);
				delimiter = ", ";
			}

			return sb.toString();
		}
	}

	public MetadataVersion getVersion() {
		return version;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public void setSupportUrl(String url) {
		this.supportUrl = url;
	}

	public void setAuthors(String[] authors) {
		this.authors = authors;
	}

	public void setVersion(MetadataVersion version) {
		this.version = version;
	}
	
	public boolean isUrlValid() {
		return new UrlValidator(new String[] { "http", "https" }).isValid(supportUrl);
	}
	
	public String toHtmlString() {
		StringBuilder sb = new StringBuilder();
		
		sb.append("<h1 style='margin-top: 5px'>").append(title).append("</h1>");
		
		sb.append("<p>");
				
		if (authors.length > 0) {
			sb.append("<b>By: </b>").append(getAuthorsString()).append("<br />");
		}
		
		sb.append("<b>Version: </b>").append(getVersion().toString()).append("<br />");
		
		if (isUrlValid()) {
			sb.append("<b>Website: </b><a target='_blank' href='").append(supportUrl).append("'>").append(supportUrl).append("</a>").append("<br />");
		}
		
		sb.append("</p>");
		
		sb.append("<hr noshade />");
		
		try {
			sb.append(new Markdown4jProcessor().process(description));
		} catch (IOException ioex) {
			sb.append("(Error parsing description Markdown)");
		}
		
		return sb.toString();
	}
}
